#ifndef DV_PING_H
#define DV_PING_H

#include <Socket.h>
#include <DateTime.h>
#include <ThreadUtil.h>
using namespace kascale;
#include "../dvmcast/rtp.h"
#include "../dvmcast/Constants.h"
#include <float.h>


class dv_ping_result
{
public:
	dv_ping_result()
	{
		packets_sent = 0;
		packets_recv = 0;
		bytes_sent = 0;
		bytes_recv = 0;
		period = 0;
		delay = 0;
		bytes_sent_ideal = 0;
	}
	dv_ping_result(const dv_ping_result& dpr)
	{
		this->operator=(dpr);
	}
	dv_ping_result& operator=(const dv_ping_result& dpr)
	{
		if(this == &dpr)
			return *this;
		packets_sent = dpr.packets_sent;
        packets_recv = dpr.packets_recv;
		bytes_sent = dpr.bytes_sent;
		bytes_recv = dpr.bytes_recv;
		period = dpr.period;
		delay = dpr.delay;
		bytes_sent_ideal = dpr.bytes_sent_ideal;
		return *this;
	}
	int32_t		packets_sent;
	int32_t		packets_recv;
	int64_t		bytes_sent;
	int64_t		bytes_recv;
	int64_t		period;
	int64_t		bytes_sent_ideal;
    double		delay;
};


class DVPinger
{
public:
	DVPinger(const IPAddress& host, const IPAddress& remote_host, in_port_t snd_port, in_port_t rcv_port);
	~DVPinger();
	bool Init();
	dv_ping_result Ping(int64_t period, double bandwidth);
	void* RecvProc(void*);
	bool Cleanup();
protected:
	void QuitRecvThread();
private:
	IPAddress	host;
	IPAddress	remote_host;
	in_port_t	snd_port;
	in_port_t	rcv_port;
	Socket		snd_sock;
	Socket		rcv_sock;
	static const int packet_size = sizeof(rtp_hdr_t) + DIF_BLOCK_SIZE * DIF_BLOCK_PER_PACKET;
	char		packet[packet_size];
	rtp_trivial_hdr_t* prth;
	rtp_hdr_t*	pRtpHdr;
	int64_t&	snd_pkt_seq;
	char		rcvbuf[packet_size];
	int64_t&	rcv_pkt_seq;
	SimpleEvent evtRecvThreadQuit;
	bool		bQuitRecv;
	thread_t	rcv_thread;
	int64_t		snd_pkt_time_cache[1000];
};

dv_ping_result dvping(const IPAddress& host, in_port_t snd_port, in_port_t rcv_port, int64_t period, double bandwidth);

#endif // !defined(DV_PING_H)

